/**
 * 
 */
package fr.upvm.lem3.vm3d.ui.swing.dataload;

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.FileOutputStream;
import java.io.Serializable;
import java.util.Vector;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.ListModel;
import javax.swing.ListSelectionModel;
import javax.swing.TransferHandler;
import javax.swing.border.Border;
import javax.swing.border.EtchedBorder;
import javax.swing.border.TitledBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;


import fr.upvm.lem3.vm3d.ui.swing.progressbar.MyProgressBar;
import fr.upvm.lem3.vm3d.ui.swing.util.RotatedIcon;
import fr.upvm.lem3.vm3d.ui.swing.util.SwingUtil;

/**
 * the window which help to transform the set of given ctf Files 
 * into one big file (this file contains voxels) before visualize 
 * the resulting file 
 *******************************************************************
 *CtfDataLoader.java
 *19.02.2012
 *@author Guy Nougouapi
 *******************************************************************
 *
 *******************************************************************
 */
public class CtfDataLoader extends JPanel implements Serializable, ListSelectionListener{

	/**
	 * 
	 */
	private static final long serialVersionUID = -1700246648939030774L;
	
	private final static String DIR_INPUT_PANEL_TITLE = "Input Directory";
	private final static String FILE_INPUT_PANEL_TITLE = "Output File";
	private final static String LISTPANEL_TITEL_TEXT = "File Selection";
	private final static String BTN_SELECT_TEXT = "Select";
	private final static String BTN_OK_TEXT = "Start";
	private final static String BTN_OK_TOOLTIP_TEXT = "Start the computation";
	private static final String CANCEL = "Cancel";
	private static final String CANCEL_TOOLTIP_TEXT = "Abort the operation";
	private final static String BTN_UP_TEXT = ">";
	private final static String BTN_UP_TOOLTIP_TEXT = "Move selection up";
	private final static String BTN_DOWN_TEXT = ">";
	private final static String BTN_DOWN_TOOLTIP_TEXT = "Move selection down";
	private final static String BTN_DELETE_TEXT = "x";
	private final static String BTN_DELETE_TOOLTIP_TEXT = "Delete selection";
	private final static String BTN_SLIDE_Right_TEXT = ">";
	private final static String BTN_SLIDE_Right_TOOLTIP_TEXT = "Slide selection into the list on the right";
	private final static String BTN_SLIDE_LEFT_TEXT = "<";
	private final static String BTN_SLIDE_LEFT_TOOLTIP_TEXT = "Slide selection into the list on the left";
	private final static String BTN_SLIDE_ALL_Right_TEXT = ">>";
	private final static String BTN_SLIDE_ALL_Right_TOOLTIP_TEXT = "Slide all at once into the list on the right";
	private final static String BTN_SLIDE_ALL_LEFT_TEXT = "<<";
	private final static String BTN_SLIDE_ALL_LEFT_TOOLTIP_TEXT = "Slide all at once into the list on the left";
	private final static String Z_STEP_TEXT = "Z Step";
	private final static String Z_STEP_TOOLTIP_TEXT = "Step of the z coordinate";
	private final static String LIST_LABEL_TEXT = "Total of ctf File(s): ";
	
	private final static String DIR_INPUT_CMD = "Input directory";
	private final static String FILE_OUTPUT_CMD = "File Output";
	private final static String START_CMD = "Start OK";
	private static final String BTN_LEFT_UP_CMD = "UP Left";
	private static final String BTN_LEFT_DOWN_CMD = "Down Left";
	private static final String BTN_LEFT_DELETE_CMD = "Delete Left";
	private static final String BTN_RIGHT_UP_CMD = "UP Right";
	private static final String BTN_RIGHT_DOWN_CMD = "Down Right";
	private static final String BTN_RIGHT_DELETE_CMD = "Delete Right";

	private static final String ALL_TO_LEFT_CMD = "SLide All Left";
	private static final String ALL_TO_RIGHT_CMD= "Slide All Right";
	private static final String TO_RIGHT_CMD= "Slide Right";
	private static final String TO_LEFT_CMD = "SLide Left";
	
	private static final String SLIDE_ALL_CMD = "Slide All";
	private static final String SLIDE_CMD = "Slide selection";
	private static final String DOWN_CMD = "Move Up";
	private static final String UP_CMD = "Move Down";
	
	protected static final String OPERATION_STARTED = "Operation in progress";
	protected static final String OPERATION_DONE = "Done !";

	private static final String ENABLE_STORAGE = "Enbale  storage";
	private static final String DISABLE_STORAGE = "Disable storage";

	
	private JPanel dirInputPanel;	//panel for the Input directory textfield
	private JPanel fileOutputPanel;	//panel for the output file textfield
	private JPanel listpanel;		// the listeboxs for picking ctf file will be placed on
	private JPanel controlPanel;
	
	private JTextField fieldInputDir;
	private JTextField fieldOutputFile;
	private JTextField fieldZStep;
	
	private JButton btnInput, btnOutput, btnStart;
	private JButton btnUpLeftList, btnDownLeftList, btnDeleteLeftList;
	private JButton btnUpRightList, btnDownRightList, btnDeleRightList;
	private JButton btnMoveToLeft, btnMoveAllToLeft, btnMoveToRight, btnMoveAllToRight;
	private JCheckBox ckBox;	//use to enable or the store of the result of the ctf parsed files on the Harddrive. 
	
	private JLabel labelNbofFileLeft, labelBnofFileRight; // display the current number of files in the respectively in the left and right box
	private JList<String> listLeft;		//list with display the ctf file containing in the given directory
	private JList<String> listRight;		//list with display the selecteded ctf file to transform and visualize if needs be
	
	private int nbofFile;			// the number of ctf File in the giving directory
	private String inputPath;		// input/ouput path of the directory and file
	private String outputPath;
	private MyProgressBar progressBar;			//custom progressBar object. It is used to display the current state of computing task
	
	private CtfDataLoaderController controller;
	
	public CtfDataLoader(String name , DataLoadController dataLoaderController){
		super();
		this.setName(name);
		setController(new CtfDataLoaderController(this,dataLoaderController));
		initComponents();
	}
	
	/**
	 * 
	 * @return
	 */
	public JCheckBox getCkBox() {
		if( ckBox == null){
			ckBox = new JCheckBox();
			ckBox.setToolTipText(DISABLE_STORAGE);
			ckBox.setBorder(BorderFactory.createEmptyBorder(1,1,1,1));
			ckBox.setSelected(true);
			ckBox.addItemListener(new ItemListener() {
				@Override
				public void itemStateChanged(ItemEvent e) {
					JCheckBox cb = (JCheckBox)e.getSource();
					if(cb.isSelected()){
						ckBox.setToolTipText(DISABLE_STORAGE);
						getFieldOutputFile().setEnabled(true);
						getBtnOutput().setEnabled(true);
					}
					else{
						ckBox.setToolTipText(ENABLE_STORAGE);
						getFieldOutputFile().setEnabled(false);
						getBtnOutput().setEnabled(false);
					}
				}
			});
		}
		return ckBox;
	}
	/**
	 * @return the btnInput
	 */
	public JButton getBtnInput() {
		if( btnInput == null){
			btnInput = createButton(BTN_SELECT_TEXT, null, true,new Insets(5, 5, 5, 5));
			btnInput.setPreferredSize(new Dimension(70,70));
			btnInput.setActionCommand(DIR_INPUT_CMD);
			btnInput.addActionListener(new MyButtonListener());
		}
		return btnInput;
	}
	/**
	 * @return the btnOutput
	 */
	public JButton getBtnOutput() {
		if( btnOutput == null){
			btnOutput = createButton(BTN_SELECT_TEXT,null,true, null);
			btnOutput.setPreferredSize(new Dimension(70,70));
			btnOutput.setActionCommand(FILE_OUTPUT_CMD);
			btnOutput.addActionListener(new MyButtonListener());
		}
		return btnOutput;
	}
	/**
	 * @return the btnStart
	 */
	public JButton getBtnStart() {
		if( btnStart == null){
			btnStart = createButton(BTN_OK_TEXT, BTN_OK_TOOLTIP_TEXT, true, null);
			btnStart.setPreferredSize(new Dimension(75,70));
			btnStart.setActionCommand(START_CMD);
			btnStart.addActionListener(new MyButtonListener());
		}
		return btnStart;
	}
	/**
	 * @return the btnUpLeftList
	 */
	public JButton getBtnUpLeftList() {
		if(btnUpLeftList == null){
			btnUpLeftList = createButton(null,BTN_UP_TOOLTIP_TEXT,false,new Insets(5, 5, 5, 5));
			SwingUtil.rotateComponentText(btnUpLeftList,BTN_UP_TEXT, RotatedIcon.Rotate.UP);
//			btnUpLeftList.setActionCommand(BTN_LEFT_UP_CMD);
			btnUpLeftList.setActionCommand(UP_CMD);
			btnUpLeftList.addActionListener(new UpDownListener(getListLeft()));
		}
		return btnUpLeftList;
	}
	
	/**
	 * @return the btnDownLeftList
	 */
	public JButton getBtnDownLeftList() {
		if(btnDownLeftList == null){
			btnDownLeftList = createButton(null,BTN_DOWN_TOOLTIP_TEXT,false,new Insets(5, 5, 5, 5));
			SwingUtil.rotateComponentText(btnDownLeftList,BTN_DOWN_TEXT, RotatedIcon.Rotate.DOWN);
//			btnDownLeftList.setActionCommand(BTN_LEFT_DOWN_CMD);
			btnDownLeftList.setActionCommand(DOWN_CMD);
			btnDownLeftList.addActionListener(new UpDownListener(getListLeft()));
		}
		return btnDownLeftList;
	}
	
	/**
	 * @return the btnDeleteLeftList
	 */
	public JButton getBtnDeleteLeftList() {
		if(btnDeleteLeftList == null){
			btnDeleteLeftList = createButton(null, BTN_DELETE_TOOLTIP_TEXT,false,new Insets(5, 5, 5, 5));
			SwingUtil.rotateComponentText(btnDeleteLeftList, BTN_DELETE_TEXT, RotatedIcon.Rotate.UP);
			btnDeleteLeftList.setActionCommand(BTN_LEFT_DELETE_CMD);
			btnDeleteLeftList.addActionListener(new DeleteButtonListener());
		}
		return btnDeleteLeftList;
	}
	/**
	 * @return the btnUpRightList
	 */
	public JButton getBtnUpRightList() {
		if(btnUpRightList == null){
			btnUpRightList = createButton(null,BTN_UP_TOOLTIP_TEXT,false,new Insets(5, 5, 5, 5));
			SwingUtil.rotateComponentText(btnUpRightList,BTN_UP_TEXT, RotatedIcon.Rotate.UP);
//			btnUpRightList.setActionCommand(BTN_RIGHT_UP_CMD);
			btnUpRightList.setActionCommand(UP_CMD);
			btnUpRightList.addActionListener(new UpDownListener(getListRight()));
		}
		return btnUpRightList;
	}
	
	/**
	 * @return the btnDownRightList
	 */
	public JButton getBtnDownRightList() {
		if(btnDownRightList == null){
			btnDownRightList = createButton(null,BTN_DOWN_TOOLTIP_TEXT,false,new Insets(5, 5, 5, 5));
			SwingUtil.rotateComponentText(btnDownRightList,BTN_DOWN_TEXT, RotatedIcon.Rotate.DOWN);
//			btnDownRightList.setActionCommand(BTN_RIGHT_DOWN_CMD);
			btnDownRightList.setActionCommand(DOWN_CMD);
			btnDownRightList.addActionListener(new UpDownListener(getListRight()));
		}
		return btnDownRightList;
	}
	
	/**
	 * @return the btnDeleRighttList
	 */
	public JButton getBtnDeleRightList() {
		if(btnDeleRightList == null){
			btnDeleRightList = createButton(null, BTN_DELETE_TOOLTIP_TEXT,false,new Insets(5, 5, 5, 5));
			SwingUtil.rotateComponentText(btnDeleRightList, BTN_DELETE_TEXT, RotatedIcon.Rotate.UP);
			btnDeleRightList.setActionCommand(BTN_RIGHT_DELETE_CMD);
			btnDeleRightList.addActionListener(new DeleteButtonListener());
		}
		return btnDeleRightList;
	}
	
	/**
	 * @return the btnMoveToLeft
	 */
	public JButton getBtnMoveToLeft() {
		if(btnMoveToLeft == null){
			btnMoveToLeft = createButton(BTN_SLIDE_LEFT_TEXT, BTN_SLIDE_LEFT_TOOLTIP_TEXT,false, new Insets(3, 7, 3, 7));
			btnMoveToLeft.addActionListener(new SlideEltOneListToAnotherListener(getListRight(), getListLeft()));
			btnMoveToLeft.setActionCommand(SLIDE_CMD);
		}
		return btnMoveToLeft;
	}
	
	/**
	 * @return the btnMoveAllToLeft
	 */
	public JButton getBtnMoveAllToLeft() {
		if(btnMoveAllToLeft == null){
			btnMoveAllToLeft = createButton(BTN_SLIDE_ALL_LEFT_TEXT,BTN_SLIDE_ALL_LEFT_TOOLTIP_TEXT,false,new Insets(4, 4, 4, 4));
			btnMoveAllToLeft.addActionListener(new SlideEltOneListToAnotherListener(getListRight(), getListLeft()));
			btnMoveAllToLeft.setActionCommand(SLIDE_ALL_CMD);
		}
		return btnMoveAllToLeft;
	}
	/**
	 * @return the btnMoveToRight
	 */
	public JButton getBtnMoveToRight() {
		if(btnMoveToRight == null){
			btnMoveToRight = createButton(BTN_SLIDE_Right_TEXT, BTN_SLIDE_Right_TOOLTIP_TEXT,false,new Insets(3, 7, 3, 7));
			btnMoveToRight.addActionListener(new SlideEltOneListToAnotherListener(getListLeft(), getListRight()));
			btnMoveToRight.setActionCommand(SLIDE_CMD);
		}
		return btnMoveToRight;
	}

	/**
	 * @return the btnMoveAllToRight
	 */
	public JButton getBtnMoveAllToRight() {
		if(btnMoveAllToRight == null){
			btnMoveAllToRight = createButton(BTN_SLIDE_ALL_Right_TEXT,BTN_SLIDE_ALL_Right_TOOLTIP_TEXT,false, new Insets(4, 4, 4, 4));
			btnMoveAllToRight.addActionListener(new SlideEltOneListToAnotherListener(getListLeft(), getListRight()));
			btnMoveAllToRight.setActionCommand(SLIDE_ALL_CMD);
		}
		return btnMoveAllToRight;
	}

	/**
	 * 
	 */
	private void initComponents(){
		this.setLayout(new BoxLayout(this,BoxLayout.PAGE_AXIS));
		this.add(getDirInputPanel());
		this.add(getFileOutputPanel());
		this.add(getListpanel());
		this.add(getControlPanel());
	}
	/**
	 * @return the dirInputPanel
	 */
	public JPanel getDirInputPanel() {
		if( dirInputPanel == null){
			dirInputPanel = new JPanel();
			dirInputPanel.setLayout(new BoxLayout(dirInputPanel, BoxLayout.X_AXIS));
			dirInputPanel.setPreferredSize(new Dimension(0, 50));
			dirInputPanel.setBorder(BorderFactory.createTitledBorder (
					BorderFactory.createMatteBorder (1, 0, 0, 0, Color.black), DIR_INPUT_PANEL_TITLE, TitledBorder.LEFT, TitledBorder.TOP,
						new Font("Dialog", Font.BOLD, 13)));
			dirInputPanel.add(Box.createHorizontalGlue());
			dirInputPanel.add(Box.createRigidArea(new Dimension(3,0)));
			JTextField textField = getFieldInputDir();
			dirInputPanel.add(textField);
			dirInputPanel.add(Box.createRigidArea(new Dimension(3,0)));
			dirInputPanel.add(getBtnInput());
			dirInputPanel.add(Box.createRigidArea(new Dimension(3,0)));
			dirInputPanel.setOpaque(true);
			}
		return dirInputPanel;
	}
	
	/**
	 * @param dirInputPanel the dirInputPanel to set
	 */
	public void setDirInputPanel(JPanel dirInputPanel) {
		this.dirInputPanel = dirInputPanel;
	}


	/**
	 * @return the fileInputPanel
	 */
	public JPanel getFileOutputPanel() {
		if( fileOutputPanel == null){
			
			fileOutputPanel = new JPanel();
			fileOutputPanel.setLayout(new BoxLayout(fileOutputPanel, BoxLayout.PAGE_AXIS));
//			fileOutputPanel.setPreferredSize(new Dimension(0, 50));
			fileOutputPanel.setMaximumSize(new Dimension(Integer.MAX_VALUE, fileOutputPanel.getPreferredSize().height));
			/**
			 * create the components to add on this panel
			 */
			JPanel tmpPanel = new JPanel();  //the north panel
			tmpPanel.setLayout(new BoxLayout(tmpPanel, BoxLayout.X_AXIS));
			tmpPanel.setPreferredSize(new Dimension(0, 50));
			tmpPanel.add(Box.createHorizontalGlue());
			tmpPanel.add(Box.createRigidArea(new Dimension(3,0)));
			tmpPanel.add(getCkBox());
			tmpPanel.add(Box.createRigidArea(new Dimension(3,0)));
			JTextField textField = getFieldOutputFile();
			tmpPanel.add(textField);
			tmpPanel.add(Box.createRigidArea(new Dimension(3,0)));
			tmpPanel.add(getBtnOutput());
			tmpPanel.add(Box.createRigidArea(new Dimension(3,0)));
			tmpPanel.setOpaque(true);
		
			//the south panel
			JPanel tmpPanel2 = new JPanel();
			tmpPanel2.setLayout(new FlowLayout(FlowLayout.LEFT));
			tmpPanel2.setPreferredSize(new Dimension(0, 40));
			tmpPanel2.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
			JLabel label = new JLabel(Z_STEP_TEXT);
			label.setToolTipText(Z_STEP_TOOLTIP_TEXT);
			label.setFont(new Font("Dialog", Font.BOLD, 11));
			tmpPanel2.add(label);
			tmpPanel2.add(getFieldZStep());
			tmpPanel2.setOpaque(true);
			
			//add the component to the underlayed panel
			fileOutputPanel.add(tmpPanel);
//			fileOutputPanel.add(tmpPanel2);
			fileOutputPanel.setBorder(BorderFactory.createTitledBorder (
					BorderFactory.createMatteBorder (1, 0, 0, 0, Color.black), FILE_INPUT_PANEL_TITLE, TitledBorder.LEFT, TitledBorder.TOP,
						new Font("Dialog", Font.BOLD, 13)));
			fileOutputPanel.setOpaque(true);
			}
		return fileOutputPanel;
	}


	/**
	 * @param fileInputPanel the fileInputPanel to set
	 */
	public void setFileOutputPanel(JPanel fileInputPanel) {
		this.fileOutputPanel = fileInputPanel;
	}


	/**
	 * @return the listpanel
	 */
	public JPanel getListpanel(){
		if (listpanel == null){
			listpanel = new JPanel();
			listpanel.setLayout(new BoxLayout(listpanel, BoxLayout.X_AXIS));
			listpanel.setPreferredSize(new Dimension(0,100));
			listpanel.setBorder(BorderFactory.createTitledBorder (
					BorderFactory.createMatteBorder (1, 0, 0, 0, Color.black), LISTPANEL_TITEL_TEXT, 
														TitledBorder.LEFT, TitledBorder.TOP,new Font("Dialog", Font.BOLD, 13)));
			
			listpanel.add(Box.createRigidArea(new Dimension(3,0)));
			listpanel.add(createPanel1());    						
			listpanel.add(Box.createRigidArea(new Dimension(3,0)));
			listpanel.add(createPanel2());
			listpanel.add(Box.createRigidArea(new Dimension(3,0)));
			listpanel.add(createPanel3());
			listpanel.add(Box.createRigidArea(new Dimension(3,0)));
			listpanel.add(createPanel4());
			listpanel.add(Box.createRigidArea(new Dimension(3,0)));
			listpanel.add(createPanel5());
			listpanel.add(Box.createRigidArea(new Dimension(3,0)));
			listpanel.setOpaque(true);
		}
		return listpanel;
	}
	
	/**
	 * this followed five panels will be use to create the necessary panels needed
	 * @return
	 */
	private JPanel createPanel1(){
		JPanel panel = new JPanel();
		panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
		panel.setBorder(BorderFactory.createEmptyBorder());
		panel.add(getBtnUpLeftList());
		panel.add(Box.createRigidArea(new Dimension(0,3)));
		panel.add(getBtnDownLeftList());
		panel.add(Box.createRigidArea(new Dimension(0,3)));
		panel.add(getBtnDeleteLeftList());
		return panel;
	}
	/**
	 * 
	 * @return
	 */
	private JPanel createPanel2(){
		JPanel panel = new JPanel();
		panel.setLayout(new BoxLayout(panel, BoxLayout.PAGE_AXIS));
		panel.setBorder(BorderFactory.createEmptyBorder());
		panel.add(getLabelNbofFileLeft());
		panel.add(new JScrollPane(getListLeft()));
		panel.setOpaque(true);
		return panel;
	}
	
	private JPanel createPanel3(){ 		
		JPanel panel = new JPanel();
		panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
		panel.setBorder(BorderFactory.createEmptyBorder());
		panel.add(Box.createRigidArea(new Dimension(3,0)));
		panel.add(getBtnMoveAllToLeft());
		panel.add(Box.createRigidArea(new Dimension(0,3)));
		panel.add(getBtnMoveToLeft());
		panel.add(Box.createRigidArea(new Dimension(0,3)));
		panel.add(getBtnMoveToRight());
		panel.add(Box.createRigidArea(new Dimension(0,3)));
		panel.add(getBtnMoveAllToRight());
		return panel;
	}
	
	private JPanel createPanel4(){
		JPanel panel = new JPanel();
		panel.setLayout(new BoxLayout(panel, BoxLayout.PAGE_AXIS));
		panel.setBorder(BorderFactory.createEmptyBorder());
		panel.add(getLabelBnofFileRight());
		panel.add(new JScrollPane(getListRight()));
		panel.setOpaque(true);
		return panel;
	}
	
	private JPanel createPanel5(){
			JPanel panel = new JPanel();
			panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
			panel.setBorder(BorderFactory.createEmptyBorder());
			panel.add(getBtnUpRightList());
			panel.add(Box.createRigidArea(new Dimension(0,3)));
			panel.add(getBtnDownRightList());
			panel.add(Box.createRigidArea(new Dimension(0,3)));
			panel.add(getBtnDeleRightList());
			return panel;
	}
	
//	private createRotateButton(){
//		SwingUtil.rotateComponentText(button, text, rotationDirection)
//	}
	
	/**
	 * @param listpanel the listpanel to set
	 */
	public void setListpanel(JPanel listpanel) {
		this.listpanel = listpanel;
	}

	/**
	 * @return the controlPanel
	 */
	public JPanel getControlPanel() {
		if(controlPanel == null){
			controlPanel = new JPanel();
			controlPanel.setLayout(new BoxLayout(controlPanel, BoxLayout.X_AXIS));
			controlPanel.setPreferredSize(new Dimension(0, 50));
			controlPanel.setBorder(BorderFactory.createEmptyBorder());
			controlPanel.add(Box.createRigidArea(new Dimension(3,0)));
			controlPanel.add((new JPanel()).add(getProgressBar()));
			controlPanel.add(Box.createRigidArea(new Dimension(3,0)));
			controlPanel.add(getBtnStart());
			controlPanel.add(Box.createRigidArea(new Dimension(3,0)));
			controlPanel.setOpaque(true);
		}
		return controlPanel;
	}


	/**
	 * @param controlPanel the controlPanel to set
	 */
	public void setControlPanel(JPanel controlPanel) {
		this.controlPanel = controlPanel;
	}


	/**
	 * @return the nbofFile
	 */
	public int getNbofFile() {
		return nbofFile;
	}


	/**
	 * @param nbofFile the nbofFile to set
	 */
	public void setNbofFile(int nbofFile) {
		this.nbofFile = nbofFile;
	}


	/**
	 * @return the inputPath
	 */
	public String getInputPath() {
		if(inputPath== null){
			inputPath = new String("");
		}
		return inputPath;
	}


	/**
	 * @param inputPath the inputPath to set
	 */
	public void setInputPath(String inputPath) {
		this.inputPath = inputPath;
	}


	/**
	 * @return the outputPath
	 */
	public String getOutputPath() {
		if(outputPath== null)
			outputPath = new String("");
		return outputPath;
	}


	/**
	 * @param outputPath the outputPath to set
	 */
	public void setOutputPath(String outputPath) {
		this.outputPath = outputPath;
	}


	/**
	 * @return the fieldInputDir
	 */
	public JTextField getFieldInputDir() {
		if(fieldInputDir == null){
			fieldInputDir = new JTextField();
			fieldInputDir.setText(getInputPath());
			fieldInputDir.setBackground(Color.white);
			fieldInputDir.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED, Color.white, Color.white));
			fieldInputDir.setPreferredSize(new Dimension(0, 90));
			fieldInputDir.setMaximumSize(new Dimension(Integer.MAX_VALUE, fieldInputDir.getPreferredSize().height));
			fieldInputDir.setEditable(true);
			fieldInputDir.addMouseListener(new MouseAdapter() {
				@Override
				public void mouseClicked(MouseEvent e) {
					// TODO Auto-generated method stub
					super.mouseClicked(e);
					if(e.getClickCount() == 2){
						getController().selectDirectory(fieldInputDir.getText().trim());
					}
				}
			});
		}
		return fieldInputDir;
	}


	/**
	 * @param fieldInputDir the fieldInputDir to set
	 */
	public void setFieldInputDir(JTextField fieldInputDir) {
		this.fieldInputDir = fieldInputDir;
	}


	/**
	 * @return the fieldOutputFile
	 */
	public JTextField getFieldOutputFile() {
		if(fieldOutputFile == null){
			fieldOutputFile = new JTextField();
			fieldOutputFile.setText(getOutputPath());
			fieldOutputFile.setBackground(Color.white);
			fieldOutputFile.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED, Color.white, Color.white));
			fieldOutputFile.setPreferredSize(new Dimension(0, 25));
			fieldOutputFile.setMaximumSize(new Dimension(Integer.MAX_VALUE, fieldOutputFile.getPreferredSize().height));
			fieldOutputFile.setEditable(true);
			fieldOutputFile.addMouseListener(new MouseAdapter() {
				@Override
				public void mouseClicked(MouseEvent e) {
					// TODO Auto-generated method stub
					super.mouseClicked(e);
					if(e.getClickCount() == 2){
						getController().selectFileToSave((fieldOutputFile.getText().trim()));
					}
				}
			});
		}
		return fieldOutputFile;
	}


	/**
	 * @param fieldOutputFile the fieldOutputFile to set
	 */
	public void setFieldOutputFile(JTextField fieldOutputFile) {
		this.fieldOutputFile = fieldOutputFile;
	}


	/**
	 * @return the fieldZStep
	 */
	public JTextField getFieldZStep() {
		if (fieldZStep == null){
			fieldZStep = new JTextField (new String("1"),5);      //the value 1.0 is used as default Z Step
			fieldZStep.setHorizontalAlignment(JTextField.CENTER);
			fieldZStep.setBackground(Color.white);
			fieldZStep.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED, Color.white,Color.white));
			fieldZStep.setToolTipText(Z_STEP_TOOLTIP_TEXT);
			fieldZStep.setEditable(true);
		}
		return fieldZStep;
	}


	/**
	 * @param fieldZStep the fieldZStep to set
	 */
	public void setFieldZStep(JTextField fieldZStep) {
		this.fieldZStep = fieldZStep;
	}


	/**
	 * @return the listLeft
	 */
	public JList<String> getListLeft() {
		if(listLeft == null){
			listLeft = createList();
			listLeft.setDragEnabled(true);
			listLeft.setTransferHandler(new ListTransferHandler());
//			listLeft.setSelectedIndex(-1);
			updateListLeftLabel(new String("0"));
		}
		return listLeft;
	}


	/**
	 * @param listLeft the listLeft to set
	 */
	public void setListLeft(JList<String> listLeft) {
		this.listLeft = listLeft;
	}


	/**
	 * @return the listRight
	 */
	public JList<String> getListRight() {
		if(listRight == null){
			listRight = createList();
			listRight.setDragEnabled(true);
			listRight.setTransferHandler(new ListTransferHandler());
			updateListRightLabel(new String("0"),0);
		}
		return listRight;
	}
	/**
	 * @param listRight the listRight to set
	 */
	public void setListRight(JList<String> listRight) {
		this.listRight = listRight;
	}


	/**
	 * @return the progressBar
	 */
	public MyProgressBar getProgressBar() {
		if(progressBar == null){
			//create and set the maxValue of the progressBar to the number of files which the right list contains
//			progressBar = new MyProgressBar(OPERATION_STARTED, true); 
			progressBar = new MyProgressBar(0);
			progressBar.setPreferredSize(new Dimension(0, 25));
			progressBar.setMaximumSize(new Dimension(Integer.MAX_VALUE, progressBar.getPreferredSize().height));
			progressBar.addChangeListener(new ChangeListener() {
				public void stateChanged(ChangeEvent e) {
					Object source =e.getSource();
					if(source instanceof JProgressBar){
						if( progressBar.getValue() >= progressBar.getMaximum()){
							getBtnStart().setText(BTN_OK_TEXT);
							getBtnStart().setToolTipText(BTN_OK_TOOLTIP_TEXT);
							getController().getDataLoaderController().getDataLoader().getApplyBtn().setEnabled(true);
						}else{
//							progressBar.setStringPainted(true);
							getController().getDataLoaderController().getDataLoader().getApplyBtn().setEnabled(false);
						}
					}
				}
			});
		}
		return progressBar;
	}

	/**
	 * @param progressBar the progressBar to set
	 */
	public void setProgressBar(MyProgressBar progressBar) {
		this.progressBar = progressBar;
	}


	/**
	 * @return the labelNbofFileLeft
	 */
	public JLabel getLabelNbofFileLeft() {
		if (labelNbofFileLeft == null){
			labelNbofFileLeft = new JLabel();
			labelNbofFileLeft.setHorizontalAlignment(JLabel.LEFT);
			labelNbofFileLeft.setFont(new Font("Dialog", Font.BOLD, 11));
			this.updateListLeftLabel(LIST_LABEL_TEXT);
			}
		return labelNbofFileLeft;
	}


	/**
	 * @param labelNbofFileLeft the labelNbofFileLeft to set
	 */
	public void setLabelNbofFileLeft(JLabel labelNbofFileLeft) {
		
		this.labelNbofFileLeft = labelNbofFileLeft;
	}
	/**
	 * @return the labelBnofFileRight
	 */
	public JLabel getLabelBnofFileRight() {
		if (labelBnofFileRight == null){
			labelBnofFileRight = new JLabel();
			labelBnofFileRight.setHorizontalAlignment(JLabel.LEFT);
			labelBnofFileRight.setFont(new Font("Dialog", Font.BOLD, 11));
			this.updateListRightLabel(LIST_LABEL_TEXT,0);			
		}
		return labelBnofFileRight;
	}


	/**
	 * @param labelBnofFileRight the labelBnofFileRight to set
	 */
	public void setLabelBnofFileRight(JLabel labelBnofFileRight) {
		this.labelBnofFileRight = labelBnofFileRight;
	}
	/**
	 * Add the new in parameter given text to the text on the label above the left panellist
	 * @param newText to add to the previous label text
	 * 		  
	 */
	public void updateListLeftLabel(String newText){
		String text = getLabelNbofFileLeft().getText();
		if ( !(text.startsWith(LIST_LABEL_TEXT))) 
				text = newText ;
		else
			text = text.substring(0, LIST_LABEL_TEXT.length()).concat(newText);
		
		getLabelNbofFileLeft().setText(text);
	}
	
	/**
	 * Update the Lists with the data inside the given 2 vectors
	 */
	public void updateList(Vector<String> leftVec, Vector<String> rightVec){
		if( (leftVec !=null) && (leftVec.size())!= 0 )
			((MyListModel<String>)getListLeft().getModel()).addElements(leftVec);
		if ( (rightVec !=null) && (rightVec.size())!= 0)
			((MyListModel<String>)getListRight().getModel()).addElements(rightVec);
	}
	/**
	 * Add the new in parameter given text to the text on the label above the right panellist
	 * @param newText to add to the previous label text
	 * 		  nbofElt number of elements in the box
	 */
	public void updateListRightLabel(String newText, int nbofElt){
		String text = getLabelBnofFileRight().getText();
		if ( !(text.startsWith(LIST_LABEL_TEXT))) 
				text = newText ;
		else
			text = text.substring(0, LIST_LABEL_TEXT.length()).concat(newText);
		
		//swap the availability of the Start button
		if(nbofElt != 0){
			this.getBtnStart().setEnabled(true);
		}else
			this.getBtnStart().setEnabled(false);
		
		getLabelBnofFileRight().setText(text);
	}
	/**
	 * create and return  jButton object 
	 * @param text
	 * @param toolTip
	 * @param inset for the  margin
	 * @return
	 */
	private  JButton createButton(String text, String toolTip, boolean enable, Insets inset) {
		JButton button = new JButton();
		if(text != null)
			button.setText(text);
		if( toolTip != null)
			button.setToolTipText(toolTip);
		if(inset != null)
			button.setMargin(inset);
		button.setAlignmentX(Component.CENTER_ALIGNMENT);
		button.setAlignmentY(Component.CENTER_ALIGNMENT);
		button.setEnabled(enable);
		button.setFocusable(false);
		return button;
	}
	
	/**
	 * create an empty JList with a single interval selection mode
	 * that will contains string object
	 * @return
	 */
	private JList<String> createList(){
		JList<String> list = new JList<String>(new MyListModel<String>());
		list.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
		list.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED, Color.white, Color.white));
//		list.setSelectedIndex(0);		
		list.setCellRenderer(new MyCustomCellrenderer());
		((MyListModel<String>)list.getModel()).addListDataListener(new MyListDataListener());
		list.addListSelectionListener(this);
		return list;
	}


	/**
	 * @return the controller
	 */
	public CtfDataLoaderController getController() {
		return controller;
	}

	/**
	 * @param controller the controller to set
	 */
	public void setController(CtfDataLoaderController controller) {
		this.controller = controller;
	}
  // Listener method for list selection changes.
  @Override
  public void valueChanged(ListSelectionEvent e) {
    
	  	if (e.getValueIsAdjusting() == false) {
	
		      if (getListLeft().getSelectedIndex() == -1) {
		        // No selection: disable delete, up, and down buttons.
		        getBtnUpLeftList().setEnabled(false);
		        getBtnDownLeftList().setEnabled(false);
		        getBtnDeleteLeftList().setEnabled(false);
		        getBtnMoveToRight().setEnabled(false);
		       
		      } else if (getListLeft().getSelectedIndices().length > 1) {
		        // Multiple selection: disable up and down buttons.
		    	    getBtnUpLeftList().setEnabled(false);
			        getBtnDownLeftList().setEnabled(false);
			        getBtnDeleteLeftList().setEnabled(true);
			        getBtnMoveToRight().setEnabled(true);
		
		      } else {
		        // Single selection: permit all operations.
		    	    getBtnUpLeftList().setEnabled(true);
			        getBtnDownLeftList().setEnabled(true);
			        getBtnDeleteLeftList().setEnabled(true);
			        getBtnMoveToRight().setEnabled(true);
		       
		      }
		      if (getListRight().getSelectedIndex() == -1) {
			        // No selection: disable delete, up, and down buttons.
			        getBtnUpRightList().setEnabled(false);
			        getBtnDownRightList().setEnabled(false);
			        getBtnDeleRightList().setEnabled(false);
			        getBtnMoveToLeft().setEnabled(false);
			       
			      } else if (getListRight().getSelectedIndices().length > 1) {
			        // Multiple selection: disable up and down buttons.
			    	  	getBtnUpRightList().setEnabled(false);
				        getBtnDownRightList().setEnabled(false);
				        getBtnDeleRightList().setEnabled(true);
				        getBtnMoveToLeft().setEnabled(true);
			
			      } else {
			        // Single selection: permit all operations.
			    	  	getBtnUpRightList().setEnabled(true);
				        getBtnDownRightList().setEnabled(true);
				        getBtnDeleRightList().setEnabled(true);
				        getBtnMoveToLeft().setEnabled(true);
			       
			      }
    }
  }
	
	/**
	 * Handle the event occurred on click on one off the four button with label ">>", ">", "<", and "<<"
	 *******************************************************************
	 *CtfDataLoader.java
	 *20.02.2012
	 *@author Guy Nougouapi
	 *******************************************************************
	 *
	 *******************************************************************
	 */
	protected class SlideEltOneListToAnotherListener implements ActionListener{
	
		private JList<String> source, target;
		
		public SlideEltOneListToAnotherListener(JList<String>source, JList<String>target){
			super();
			this.source = source;
			this.target = target;
		}
		public SlideEltOneListToAnotherListener(){
			super();
		}
	
	 //Code for the action to perform goes into the followed methode
	  public void actionPerformed(ActionEvent e) {
		  
		  String cmd = e.getActionCommand();
		  
			switch (cmd) {
			case SLIDE_ALL_CMD:
				// move all the elements from the source list into the target list 
				// and set those elements as selected
				Vector<String> vec = ((MyListModel<String>)source.getModel()).getData();
				((MyListModel<String>)source.getModel()).clear();
				((MyListModel<String>)target.getModel()).addElements(vec);
				//set the new added elements as selected
				setSelectedIndices(target, vec.size());
				break;
				
			case SLIDE_CMD:
				//move only the selected element(s) from source to target
				int[] indices = source.getSelectedIndices();
				Vector<String> newElements  = ((MyListModel<String>)source.getModel()).getElements(indices);
				((MyListModel<String>)target.getModel()).addAll(newElements);
				if (indices.length > 1)
						((MyListModel<String>)source.getModel()).removeRange(indices[0], indices[indices.length-1]);
				else
						((MyListModel<String>)source.getModel()).removeRange(indices[0], indices[0]);
				setSelectedIndices(target, indices.length);
				
				//select one items in the source. This ist last Item.
				if(source.getModel().getSize() > 0)
					source.setSelectedIndex( source.getModel().getSize() -1);
				break;	
			default:
				break;
			}
	  }
	  
	/**
	 * 
	 */
	 private void setSelectedIndices(JList list, int range){
		 int[]  selectedIndices = new int[range];
	        int startSelectionx= list.getModel().getSize() - range;
	        for(int i = 0; i < selectedIndices.length; i++){
	        	selectedIndices[i]= startSelectionx++;
	        }
	        list.setSelectedIndices(selectedIndices);
	 }
 }
	
	/**
	 * implementation of the listening on data change
	 *******************************************************************
	 *CtfDataLoader.java
	 *20.02.2012
	 *@author Guy Nougouapi
	 *******************************************************************
	 * 
	 *******************************************************************
	 */
  class MyListDataListener implements ListDataListener {
	  	
		@Override
		public void intervalAdded(ListDataEvent e) {
			updatelabel();
		}

		@Override
		public void intervalRemoved(ListDataEvent e) {
			updatelabel();
		}

		@Override
		public void contentsChanged(ListDataEvent e) {
			updatelabel();
		}
		
		private void updatelabel(){
			/**
			 * Update both list left and right label
			 * 
			 */
			int lLeftElts = ((MyListModel<String>)getListLeft().getModel()).getSize();
			int lRightElts = ((MyListModel<String>)getListRight().getModel()).getSize();
			updateListLeftLabel(Integer.toString(lLeftElts));
			updateListRightLabel(Integer.toString(lRightElts), lRightElts);
			
			// enable swicth the availability of the two buttons for left and right slide
			if(lLeftElts > 0 ){
				if (  !getBtnMoveAllToRight().isEnabled())
					getBtnMoveAllToRight().setEnabled(true);
			}else{
				getBtnMoveAllToRight().setEnabled(false);
			}
			if (lRightElts > 0 ){
				if ( !getBtnMoveAllToLeft().isEnabled())
					getBtnMoveAllToLeft().setEnabled(true);
			}else{
				getBtnMoveAllToLeft().setEnabled(false);
			}
		}

  }
  
  /**Listen for clicks on the up and down arrow buttons.
   * 
   *******************************************************************
   *CtfDataLoader.java
   *21.02.2012
   *@author Guy Nougouapi
   *******************************************************************
   *
   *******************************************************************
   */
  class UpDownListener implements ActionListener {
	
		private JList<String> list;
		public UpDownListener(JList<String>list){
			super();
			this.setList(list);
		}
		public UpDownListener(){
			super();
		}
		
		@Override
	    public void actionPerformed(ActionEvent e) {
	      int moveMe = getList().getSelectedIndex();
	      String cmd = e.getActionCommand();
	      
		      switch (cmd) {
				case UP_CMD:
				        if (moveMe != 0) {
				          // not already at top
				          swap(moveMe, moveMe - 1);
				          getList().setSelectedIndex(moveMe - 1);
				          getList().ensureIndexIsVisible(moveMe - 1);
				        }
				        break;
				case DOWN_CMD:
					 if (moveMe != getList().getModel().getSize() - 1) {
				          // not already at bottom
				          swap(moveMe, moveMe + 1);
				          getList().setSelectedIndex(moveMe + 1);
				          getList().ensureIndexIsVisible(moveMe + 1);
				        }
					break;
				default:
					break;
		      }
		
		} 
		      
	  /**
	   * Swap two elements in the list.
	   * @param a first index
	   * @param b second index
	   */
	  private void swap(int a, int b) {
		   String strA = (String)getList().getModel().getElementAt(a);
		   String strB = (String)getList().getModel().getElementAt(b);
		   ( (MyListModel<String>) getList().getModel()).set(a, strB);
		   ( (MyListModel<String>) getList().getModel()).set(b, strA);
	 }
	/**
	 * @return the list
	 */
	public JList<String> getList() {
		return list;
	}
	/**
	 * @param list the list to set
	 */
	public void setList(JList<String> list) {
		this.list = list;
	}
  }
  
  /**
   * 
   *******************************************************************
   *CtfDataLoader.java
   *21.02.2012
   *@author Guy Nougouapi
   *******************************************************************
   *
   *******************************************************************
   */
  class DeleteButtonListener implements ActionListener {
	  
	    public void actionPerformed(ActionEvent e) {
	      /*
	       * This method can be called only if there's a valid selection, so go
	       * ahead and remove whatever's selected.
	       */
	     String cmd = e.getActionCommand();
	     ListSelectionModel lsm ;
	      int firstSelected ;
	      int lastSelected ;
	      
	     switch (cmd) {
		case BTN_LEFT_DELETE_CMD:
			System.out.println(cmd);
		      lsm = getListLeft().getSelectionModel();
		      firstSelected = lsm.getMinSelectionIndex();
		      lastSelected = lsm.getMaxSelectionIndex();
		      ((MyListModel<String>)getListLeft().getModel()).removeRange(firstSelected, lastSelected);
		      
		      int size =  ((MyListModel<String>)getListLeft().getModel()).size();
		      // Adjust the selection.
		      if (firstSelected ==  size) {
	          // Removed item in last position.
		    	  firstSelected--;
		      }
		      getListLeft().setSelectedIndex(firstSelected);
			break;
			
		case BTN_RIGHT_DELETE_CMD:
				 lsm = getListRight().getSelectionModel();
				 firstSelected = lsm.getMinSelectionIndex();
				 lastSelected = lsm.getMaxSelectionIndex();
				((MyListModel<String>)getListRight().getModel()).removeRange(firstSelected, lastSelected);
				
				 int size2 =  ((MyListModel<String>)getListRight().getModel()).size();
			      // Adjust the selection.
			      if (firstSelected == size2) {
		          // Removed item in last position.
			    	  firstSelected--;
			      }
			      getListRight().setSelectedIndex(firstSelected);
			break;
		default:
			break;
		}
	    
	   }
  }
 
  /**
	 * Listner event on the button with has register
	 *******************************************************************
	 *Lem3DataLoader.java
	 *21.02.2012
	 *@author Guy Nougouapi
	 *******************************************************************
	 *
	 *******************************************************************
	 */
	class MyButtonListener implements ActionListener{
		
	    Thread thread;
	    
		@Override
		public void actionPerformed(ActionEvent e) {
			String cmd = e.getActionCommand();
			JButton btn = (JButton)e.getSource();
			switch (cmd) {
			case DIR_INPUT_CMD:
				getController().selectDirectory(getFieldInputDir().getText().trim());
				break;
			case FILE_OUTPUT_CMD:
				getController().selectFileToSave(getFieldOutputFile().getText().trim());
				break;
			case START_CMD:
				if(btn.getText().equals(BTN_OK_TEXT)){
					thread =new Thread( 
							(new Runnable() {
							@Override
							public void run() {
//								synchronized(this.getClass()){
									System.out.println("The thread has been launched");
									getProgressBar().setValue(0);
//									getProgressBar().setString(OPERATION_STARTED);
//									getProgressBar().updateValue(0, OPERATION_STARTED);
									getController().startParsingFiles();
									//notify the user that the operation has finished by update the value of  the progress bar to it max 
//									if(! interrupted())
//											getProgressBar().setValue(100);
//									}
								}
						})
				);
				thread.setName("CtfLoader");
				thread.start();
				//turn it text label into "Cancel"
				btn.setText(CANCEL);
				btn.setToolTipText(CANCEL_TOOLTIP_TEXT);
					}else{
						
						System.out.println("Cancel button");
						// Kill the running thread with the name "Lem3Loader"
						//stop the timer for the progressbar
						Thread[] threads = new Thread[Thread.activeCount()];
						Thread.enumerate(threads);
						for(Thread ct: threads){
							if(ct.getName().equals("CtfLoader")){
								ct.interrupt();
								System.out.println("Thread interrupted !");
								}
						}
						btn.setText(BTN_OK_TEXT);
						btn.setToolTipText(BTN_OK_TOOLTIP_TEXT);
						getProgressBar().setValue(0);
						progressBar.setStringPainted(false);
						getController().stopParsing();
					}
				break;
			default:
				break;
			}
			
		}
		
	}
}

